#include "TemperatureChart.h"
#include <QDebug>
#include <QFontMetrics>

TemperatureChart::TemperatureChart(QWidget *parent) : QWidget(parent) {
    m_fixedSizeMode = false;
    m_fixedWidth = 580;
    m_fixedHeight = 300;
    m_scaleFactor = 1.0;
    m_margin = 25;  // 默认边距
    
    // 设置背景色为白色
    setStyleSheet("background-color: white;");
    
    // 启用鼠标跟踪（以便实时显示悬停提示）
    setMouseTracking(true);
}

void TemperatureChart::setData(const QList<TempData> &data) {
    m_tempList = data;
    update();  // 触发重绘
}

void TemperatureChart::setFixedSizeMode(bool fixed, int width, int height) {
    m_fixedSizeMode = fixed;
    m_fixedWidth = width;
    m_fixedHeight = height;
    
    if (m_fixedSizeMode) {
        setFixedSize(m_fixedWidth, m_fixedHeight);
        m_margin = 60;  // 固定尺寸时使用较大边距
    } else {
        setMinimumSize(300, 200);  // 设置最小尺寸，防止过小
        m_margin = qMax(40, static_cast<int>(50 * m_scaleFactor));  // 自适应边距
        updateGeometry();
    }
    
    update();  // 触发重绘
}

void TemperatureChart::paintEvent(QPaintEvent *event) {
    Q_UNUSED(event);
    
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);  // 抗锯齿，使线条更平滑
    
    // 计算实际绘图区域（留出边距）
    QRect drawRect = rect().adjusted(m_margin, m_margin, -m_margin, -m_margin);
    
    if (drawRect.width() <= 0 || drawRect.height() <= 0) {
        return;  // 绘图区域无效时直接返回
    }
    
    // 绘制坐标轴和网格
    drawAxes(painter, drawRect);
    
    // 绘制折线和数据点
    if (!m_tempList.isEmpty()) {
        drawLines(painter, drawRect);
        drawLegend(painter, drawRect);
    }
}

void TemperatureChart::mouseMoveEvent(QMouseEvent *event) {
    if (m_tempList.isEmpty()) {
        QToolTip::hideText();
        return;
    }
    
    // 计算实际绘图区域
    QRect drawRect = rect().adjusted(m_margin, m_margin, -m_margin, -m_margin);
    
    if (!drawRect.contains(event->pos())) {
        QToolTip::hideText();  // 鼠标不在绘图区域内
        return;
    }
    
    // 计算X轴步长（每个数据点之间的距离）
    int xStep = drawRect.width() / (m_tempList.size() - 1);
    if (xStep <= 0) return;
    
    // 计算鼠标所在的日期索引
    int index = qBound(0, (event->x() - drawRect.left()) / xStep, m_tempList.size() - 1);
    
    // 获取温度范围
    int minTemp = 100, maxTemp = -100;
    for (const auto &data : m_tempList) {
        minTemp = qMin(minTemp, data.low);
        maxTemp = qMax(maxTemp, data.high);
    }
    minTemp -= 2;
    maxTemp += 2;
    
    // 计算该日期的最高温和最低温的Y坐标
    int highY = tempToY(m_tempList[index].high, minTemp, maxTemp, drawRect);
    int lowY = tempToY(m_tempList[index].low, minTemp, maxTemp, drawRect);
    
    // 检查鼠标是否接近数据点（误差范围）
    int pointX = drawRect.left() + index * xStep;
    int highDistance = qAbs(event->y() - highY);
    int lowDistance = qAbs(event->y() - lowY);
    
    if (highDistance < 15 || lowDistance < 15) {
        QString tip = QString("%1\n最高温: %2℃\n最低温: %3℃")
                          .arg(m_tempList[index].date)
                          .arg(m_tempList[index].high)
                          .arg(m_tempList[index].low);
        QToolTip::showText(event->globalPos(), tip, this);
    } else {
        QToolTip::hideText();
    }
}

void TemperatureChart::resizeEvent(QResizeEvent *event) {
    Q_UNUSED(event);
    
    // 计算缩放因子（基于初始尺寸）
    if (!m_fixedSizeMode) {
        int baseWidth = 580;
        m_scaleFactor = static_cast<double>(width()) / baseWidth;
        m_scaleFactor = qMax(0.5, qMin(1.5, m_scaleFactor));  // 限制缩放范围
        m_margin = qMax(40, static_cast<int>(50 * m_scaleFactor));  // 自适应边距
    }
    
    update();  // 重绘图表
}

void TemperatureChart::drawAxes(QPainter &painter, const QRect &drawRect) {
    if (m_tempList.isEmpty()) return;
    
    // 设置画笔和字体
    QPen axisPen(QColor(50, 50, 50), 2);
   
    QPen gridPen(QColor( 37, 187, 112), 1, Qt::DashLine);
    QFont labelFont("SimHei", 10);
    QFont titleFont("SimHei", 12, QFont::Bold);
    
    painter.setPen(axisPen);
    painter.setFont(labelFont);
    
    // 绘制X轴和Y轴
    painter.drawLine(drawRect.bottomLeft(), drawRect.bottomRight());  // X轴
    painter.drawLine(drawRect.topLeft(), drawRect.bottomLeft());       // Y轴
    
    // 计算温度范围
    int minTemp = 100, maxTemp = -100;
    for (const auto &data : m_tempList) {
        minTemp = qMin(minTemp, data.low);
        maxTemp = qMax(maxTemp, data.high);
    }
    minTemp -= 2;
    maxTemp += 2;
    int yRange = maxTemp - minTemp;
    if (yRange <= 0) yRange = 1;
    
    // 绘制X轴标签（日期）
    int xStep = drawRect.width() / (m_tempList.size() - 1);
    for (int i = 0; i < m_tempList.size(); ++i) {
        int x = drawRect.left() + i * xStep;
        
        // 绘制刻度线
        painter.drawLine(x, drawRect.bottom(), x, drawRect.bottom() + 5);
        
        // 绘制日期标签
        QString dateText = m_tempList[i].date;
        
        // 调整字体大小，确保标签不会超出边界
        QFont adjustedFont = adjustFontSize(labelFont, dateText, 
                                            QRect(x - 30, drawRect.bottom() + 10, 60, 20), 
                                            painter);
        painter.setFont(adjustedFont);
        
        painter.drawText(x - 30, drawRect.bottom() + 10, 60, 20, 
                         Qt::AlignCenter, dateText);
    }
    
    // 绘制Y轴标签（温度）
    int yStep = 5;  // 温度间隔
    int yTickCount = (maxTemp - minTemp) / yStep + 1;
    for (int i = 0; i < yTickCount; ++i) {
        int temp = minTemp + i * yStep;
        int y = tempToY(temp, minTemp, maxTemp, drawRect);
        
        // 绘制刻度线
        painter.drawLine(drawRect.left() - 5, y, drawRect.left(), y);
        
        // 绘制温度标签
        QString tempText = QString("%1℃").arg(temp);
        
        // 调整字体大小，确保标签不会超出边界
        QFont adjustedFont = adjustFontSize(labelFont, tempText, 
                                            QRect(drawRect.left() - 40, y - 10, 40, 20), 
                                            painter);
        painter.setFont(adjustedFont);
        
        painter.drawText(drawRect.left() - 40, y - 10, 40, 20, 
                         Qt::AlignRight | Qt::AlignVCenter, tempText);
    }
    
    // 绘制网格线
    painter.setPen(gridPen);
    
    // 垂直网格线
    for (int i = 0; i < m_tempList.size(); ++i) {
        int x = drawRect.left() + i * xStep;
        painter.drawLine(x, drawRect.top(), x, drawRect.bottom());
    }
    
    // 水平网格线
    for (int i = 0; i < yTickCount; ++i) {
        int temp = minTemp + i * yStep;
        int y = tempToY(temp, minTemp, maxTemp, drawRect);
        painter.drawLine(drawRect.left(), y, drawRect.right(), y);
    }
    
    // 绘制轴标题
    painter.setFont(titleFont);
    
    // X轴标题
    painter.drawText(drawRect.center().x() - 30, drawRect.bottom() + 50, "日期");
    
    // Y轴标题（旋转90度）
    painter.save();
    painter.translate(drawRect.left() - 30, drawRect.center().y());
    painter.rotate(-90);
    painter.drawText(-30, -10, "温度");
    painter.restore();
}

void TemperatureChart::drawLines(QPainter &painter, const QRect &drawRect) {
    if (m_tempList.size() < 2) return;
    
    // 计算温度范围
    int minTemp = 100, maxTemp = -100;
    for (const auto &data : m_tempList) {
        minTemp = qMin(minTemp, data.low);
        maxTemp = qMax(maxTemp, data.high);
    }
    minTemp -= 2;
    maxTemp += 2;
    int yRange = maxTemp - minTemp;
    if (yRange <= 0) yRange = 1;
    
    // 计算X轴步长
    int xStep = drawRect.width() / (m_tempList.size() - 1);
    
    // 绘制最高温折线
    QPen highPen(QColor(255, 50, 50), 2);
    painter.setPen(highPen);
    QVector<QPoint> highPoints;
    
    for (int i = 0; i < m_tempList.size(); ++i) {
        int x = drawRect.left() + i * xStep;
        int y = tempToY(m_tempList[i].high, minTemp, maxTemp, drawRect);
        highPoints.append(QPoint(x, y));
    }
    
    painter.drawPolyline(highPoints.data(), highPoints.size());
    
    // 绘制最高温数据点
    painter.setBrush(QColor(255, 50, 50));
    for (const QPoint &p : highPoints) {
        painter.drawEllipse(p, 4, 4);
    }
    
    // 绘制最低温折线
    QPen lowPen(QColor(50, 50, 255), 2);
    painter.setPen(lowPen);
    QVector<QPoint> lowPoints;
    
    for (int i = 0; i < m_tempList.size(); ++i) {
        int x = drawRect.left() + i * xStep;
        int y = tempToY(m_tempList[i].low, minTemp, maxTemp, drawRect);
        lowPoints.append(QPoint(x, y));
    }
    
    painter.drawPolyline(lowPoints.data(), lowPoints.size());
    
    // 绘制最低温数据点
    painter.setBrush(QColor(50, 50, 255));
    for (const QPoint &p : lowPoints) {
        painter.drawEllipse(p, 4, 4);
    }
}

void TemperatureChart::drawLegend(QPainter &painter, const QRect &drawRect) {
    if (m_tempList.isEmpty()) return;
    
    QFont legendFont("SimHei", 8);
    painter.setFont(legendFont);
    
    // 图例位置（右上角）
    QRect legendRect(drawRect.right() - 120, drawRect.top() - 25, 120, 30);
    
    // 绘制图例背景
    painter.setBrush(QColor(255, 255, 255, 200));
    painter.setPen(QColor(200, 200, 200));
    painter.drawRoundedRect(legendRect, 5, 5);
    
    // 绘制最高温图例
    painter.setPen(QColor(255, 50, 50));
    painter.setBrush(QColor(255, 50, 50));
    painter.drawEllipse(legendRect.left() + 10, legendRect.top() + 8, 6, 6);
    painter.setPen(QColor(0, 0, 0));
    painter.drawText(legendRect.left() + 25, legendRect.top() + 15, "最高温");
    
    // 绘制最低温图例
    painter.setPen(QColor(50, 50, 255));
    painter.setBrush(QColor(50, 50, 255));
    painter.drawEllipse(legendRect.left() + 70, legendRect.top() + 8, 6, 6);
    painter.setPen(QColor(0, 0, 0));
    painter.drawText(legendRect.left() + 85, legendRect.top() + 15, "最低温");
}

int TemperatureChart::tempToY(int temp, int minTemp, int maxTemp, const QRect &drawRect) {
    // 将温度值映射到Y坐标
    return drawRect.bottom() - (temp - minTemp) * 1.0 / (maxTemp - minTemp) * drawRect.height();
}

QFont TemperatureChart::adjustFontSize(const QFont &baseFont, const QString &text, 
                                       const QRect &availableRect, QPainter &painter) {
    QFont font = baseFont;
    QFontMetrics fm(font);
    
    // 检查文本是否超出可用区域
    while (fm.width(text) > availableRect.width() || fm.height() > availableRect.height()) {
        // 如果文本太大，减小字体大小
        int pointSize = font.pointSize();
        if (pointSize > 6) {  // 最小字体大小限制
            font.setPointSize(pointSize-1);
            fm = QFontMetrics(font);
        } else {
            break;  // 达到最小字体大小，不再减小
        }
    }
    
    return font;
}
